#include "stm32f10x.h"                  // Device header


void DAC_Channel1_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );	  //使能PORTA通道时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 		 //模拟输入
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//DAC通道1输出初始化
void DAC1_Init(void)
{
	DAC_InitTypeDef DAC_InitType;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 
	DAC_Channel1_GPIO_Init();
					
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Enable ;	//DAC1输出缓存关闭 BOFF1=1
  DAC_Init(DAC_Channel_1,&DAC_InitType);	 //初始化DAC通道1
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值
	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1
}
 
//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void DAC1_SetVol(u16 vol)
{
	float temp=vol;
	temp/=3300;
	temp*=4095;
	DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
}


#define TRIANGLE_WAVE_SAMPLES 300 // 正弦波采样点数
uint16_t triangleWave[TRIANGLE_WAVE_SAMPLES];

void GenerateTriangleWave(void) {
	for (int i = 0; i < TRIANGLE_WAVE_SAMPLES/2; i++) {
        triangleWave[i] = (uint16_t)(4095.0/TRIANGLE_WAVE_SAMPLES*2*i); // 12位DAC
  }
	for (int i = TRIANGLE_WAVE_SAMPLES/2; i < TRIANGLE_WAVE_SAMPLES; i++) {
        triangleWave[i] = (uint16_t)(4096*2-1-4095.0/TRIANGLE_WAVE_SAMPLES*2*i); // 12位DAC
  }
}

void DAC_TriangleWave_Config(void) {
		GenerateTriangleWave();
    // 启用DAC和DMA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	
		// 配置定时器6
    TIM_TimeBaseInitTypeDef TIM_InitStruct;
    TIM_InitStruct.TIM_Period = 0x200; // 定时器周期，决定三角波频率
    TIM_InitStruct.TIM_Prescaler = 0; // 预分频器
    TIM_InitStruct.TIM_ClockDivision = 0;
    TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
	
    TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
		TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
    TIM_Cmd(TIM6 , ENABLE);

    // 配置DAC
    DAC_InitTypeDef DAC_InitStruct;
    DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; // 定时器6触发
    DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; // 无波形生成
    DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // 启用输出缓冲
    DAC_Init(DAC_Channel_1, &DAC_InitStruct);

    // 配置DMA
    DMA_InitTypeDef DMA_InitStruct;
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1; // DAC数据寄存器地址
    DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)triangleWave; // 正弦波数据表地址
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; // 内存到外设
    DMA_InitStruct.DMA_BufferSize = TRIANGLE_WAVE_SAMPLES; // 数据传输量
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不变
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16位数据
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16位数据
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 循环模式
    DMA_InitStruct.DMA_Priority = DMA_Priority_High; // 高优先级
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存模式
    DMA_Init(DMA2_Channel3, &DMA_InitStruct);
		

    // 启用DMA
    DMA_Cmd(DMA2_Channel3, ENABLE);

    // 启用DAC DMA请求
    DAC_DMACmd(DAC_Channel_1, ENABLE);

    // 启用DAC通道1
    DAC_Cmd(DAC_Channel_1, ENABLE);
}

//void DAC_TriangleWave_Config(void) {
//    // 启用DAC和定时器时钟
//    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
//		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
//		DAC_Channel1_GPIO_Init();
//    // 配置DAC
//    DAC_InitTypeDef DAC_InitStruct;
//    DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; // 定时器6触发
//    DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Triangle; // 三角波模式
//    DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023; // 三角波幅度
//    DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // 启用输出缓冲
//    DAC_Init(DAC_Channel_1, &DAC_InitStruct);
//		DAC_SetChannel1Data(DAC_Align_12b_R,0);
//    // 配置定时器6
//    TIM_TimeBaseInitTypeDef TIM_InitStruct;
//    TIM_InitStruct.TIM_Period = 0x20; // 定时器周期，决定三角波频率
//    TIM_InitStruct.TIM_Prescaler = 0; // 预分频器
//    TIM_InitStruct.TIM_ClockDivision = 0;
//    TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
//	
//    TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
//		TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
//    TIM_Cmd(TIM6 , ENABLE);

//    // 启用DAC通道1
//    DAC_Cmd(DAC_Channel_1, ENABLE);
//}

#include <math.h>

#define SINE_WAVE_SAMPLES 300 // 正弦波采样点数

#define M_PI 3.1415926
uint16_t sineWave[SINE_WAVE_SAMPLES]; // 正弦波数据表


void GenerateSineWave(void) {
    for (int i = 0; i < SINE_WAVE_SAMPLES; i++) {
        sineWave[i] = (uint16_t)(2048 * (1 + sin(2 * M_PI * i / SINE_WAVE_SAMPLES))); // 12位DAC
    }
}



void DAC_SinWave_Config(void) {
		GenerateSineWave();
    // 启用DAC和DMA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	
		// 配置定时器6
    TIM_TimeBaseInitTypeDef TIM_InitStruct;
    TIM_InitStruct.TIM_Period = 0x200; // 定时器周期，决定三角波频率
    TIM_InitStruct.TIM_Prescaler = 0; // 预分频器
    TIM_InitStruct.TIM_ClockDivision = 0;
    TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
	
    TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
		TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
    TIM_Cmd(TIM6 , ENABLE);

    // 配置DAC
    DAC_InitTypeDef DAC_InitStruct;
    DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; // 定时器6触发
    DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; // 无波形生成
    DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // 启用输出缓冲
    DAC_Init(DAC_Channel_1, &DAC_InitStruct);

    // 配置DMA
    DMA_InitTypeDef DMA_InitStruct;
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1; // DAC数据寄存器地址
    DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)sineWave; // 正弦波数据表地址
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; // 内存到外设
    DMA_InitStruct.DMA_BufferSize = SINE_WAVE_SAMPLES; // 数据传输量
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不变
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16位数据
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16位数据
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 循环模式
    DMA_InitStruct.DMA_Priority = DMA_Priority_High; // 高优先级
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存模式
    DMA_Init(DMA2_Channel3, &DMA_InitStruct);
		

    // 启用DMA
    DMA_Cmd(DMA2_Channel3, ENABLE);

    // 启用DAC DMA请求
    DAC_DMACmd(DAC_Channel_1, ENABLE);

    // 启用DAC通道1
    DAC_Cmd(DAC_Channel_1, ENABLE);
}
